package io.jsen.meta.diff.context;

import com.google.common.collect.Maps;
import io.jsen.meta.diff.field.MetaField;
import io.jsen.meta.diff.obj.Convert;
import io.jsen.meta.diff.obj.MetaObject;

import java.util.Map;

/**
 * 注册类型转换器
 * <p>
 * native -> meta
 * <p>
 * meta -> native
 *
 * @author jsen
 * @date 2021/4/6
 */
class MetaObjectConvertContext {

    private static final Map<Class<?>, Convert<?, ?>> CONVERT_MAP = Maps.newHashMap();

    static <S, T> void register(Class<?> clazz, Convert<S, T> convert) {
        CONVERT_MAP.put(clazz, convert);
    }

    @SuppressWarnings("unchecked")
    static <S, T> T convert(MetaField field, S s) {
        if (s instanceof Enum) {
            return ((Convert<S, T>) CONVERT_MAP.get(Enum.class)).convert(field, s);
        }
        return ((Convert<S, T>) CONVERT_MAP.get(s.getClass())).convert(field, s);
    }


    private static boolean support(Class<?> clazz) {
        return CONVERT_MAP.containsKey(clazz);
    }

    static <S> boolean supportMeta(S s) {
        return s instanceof MetaObject && support(s.getClass());
    }

    static <S> boolean supportNative(S s) {
        if (s instanceof MetaObject) {
            return false;
        }
        if (s instanceof Enum) {
            return support(Enum.class);
        }
        return support(s.getClass());
    }

    private MetaObjectConvertContext() {
    }
}
